#include "zhi.h"
//新建list对象,元素个数为elementNum
list对象S* 新建list对象(虚拟机* 虚拟机S, uint32_t elementNum) {
   //存储list元素的缓冲区
   Value* elementArray = NULL;

   //先分配内存,后调用initObjHeader,避免gc无谓的遍历
   if (elementNum > 0) {
      elementArray = 分配数组内存M(虚拟机S, Value, elementNum);
   }
   list对象S* objList = 分配指定类型的内存块M(虚拟机S, list对象S); 

   objList->elements.数据缓冲区 = elementArray;
   objList->elements.数组容量 = objList->elements.count = elementNum;
   初始化对象头(虚拟机S, &objList->objHeader, 对象类型_列表, 虚拟机S->listClass);
   return objList;
}

//在objlist中索引为index处插入value, 类似于list[index] = value
void 在list对象index索引处插入值(虚拟机* 虚拟机S, list对象S* objList, uint32_t index, Value value) {
   if (index > objList->elements.count - 1) {
      runtime_错误("index out bounded!");
   }

   if (VALUE_IS_OBJ(value)) {
      将obj作为临时根对象(虚拟机S, VALUE_TO_OBJ(value));
   }
   //准备一个Value的空间以容纳新元素产生的空间波动
   //即最后一个元素要后移1个空间
   ValueBufferAdd(虚拟机S, &objList->elements, VT_TO_VALUE(值类型_空));
   if (VALUE_IS_OBJ(value)) {
      去掉临时根对象(虚拟机S);
   }
   
   //下面使index后面的元素整体后移一位
   uint32_t idx = objList->elements.count - 1;
   while (idx > index) {
      objList->elements.数据缓冲区[idx] = objList->elements.数据缓冲区[idx - 1];
      idx--;
   }

   //在index处插入数值
   objList->elements.数据缓冲区[index] = value;
}

//调整list容量
static void 调整list容量(虚拟机* 虚拟机S, list对象S* objList, uint32_t newCapacity) {
   uint32_t 旧内存大小 = objList->elements.数组容量 * sizeof(Value);
   uint32_t 新内存大小 = newCapacity * sizeof(Value);
   内存管理器(虚拟机S, objList->elements.数据缓冲区, 旧内存大小, 新内存大小);
   objList->elements.数组容量 = newCapacity;
}

//删除list中索引为index处的元素,即删除list[index]
Value 删除list中索引值为index的元素(虚拟机* 虚拟机S, list对象S* objList, uint32_t index) {
   Value valueRemoved = objList->elements.数据缓冲区[index];

   if (VALUE_IS_OBJ(valueRemoved)) {
      将obj作为临时根对象(虚拟机S, VALUE_TO_OBJ(valueRemoved));
   }
   //使index后面的元素前移一位,覆盖index处的元素
   uint32_t idx = index;
   while (idx < objList->elements.count) {
      objList->elements.数据缓冲区[idx] = objList->elements.数据缓冲区[idx + 1];
      idx++;
   }

   //若容量利用率过低就减小容量
   uint32_t _capacity = objList->elements.数组容量 / 容量增长因子M;
   if (_capacity > objList->elements.count) {
      调整list容量(虚拟机S, objList, _capacity);
   }
   if (VALUE_IS_OBJ(valueRemoved)) {
      去掉临时根对象(虚拟机S);
   }

   objList->elements.count--;
   return valueRemoved;
}
